#ifndef Queue_TS_h
#define Queue_TS_h

#include <Windows.h>
#include "Queue.h"


namespace TL {
    template<class T> class Queue_TS : protected Queue<T> {
    protected:
        mutable CRITICAL_SECTION m_LockObject;

    public:
        Queue_TS() : Queue()
        {
            InitializeCriticalSection(&m_LockObject);
        }
        ~Queue_TS()
        {
            DeleteCriticalSection(&m_LockObject);
        }

        void Clear()
        {
            EnterCriticalSection(&m_LockObject);
            {
                Queue::Clear();
            }
            LeaveCriticalSection(&m_LockObject);
        }
        bool IsEmpty() const
        {
            bool return_value;

            EnterCriticalSection(&m_LockObject);
            {
                return_value = Queue::IsEmpty();
            }
            LeaveCriticalSection(&m_LockObject);

            return return_value;
        }
        T Pop()
        {
            T return_value;

            EnterCriticalSection(&m_LockObject);
            {
                return_value = Queue::Pop();
            }
            LeaveCriticalSection(&m_LockObject);

            return return_value;
        }
        void Push(const T &value)
        {
            EnterCriticalSection(&m_LockObject);
            {
                Queue::Push(value);
            }
            LeaveCriticalSection(&m_LockObject);
        }
        int Size() const
        {
            int return_value;

            EnterCriticalSection(&m_LockObject);
            {
                return_value = Queue::Size();
            }
            LeaveCriticalSection(&m_LockObject);

            return return_value;
        }
    };
}

#endif
